package main

import (
	"Student_Mental/controller/Client"
	"Student_Mental/controller/Middleware"
	"Student_Mental/controller/TimedTasks"
	"Student_Mental/controller/login"
	public_C "Student_Mental/controller/public"
	student_c "Student_Mental/controller/student"
	"Student_Mental/controller/teacher/booking"
	setcarousel "Student_Mental/controller/teacher/carousel"
	tea_client "Student_Mental/controller/teacher/client"
	teacher_que "Student_Mental/controller/teacher/questions"
	"Student_Mental/controller/teacher/scl90"
	teacher_stu "Student_Mental/controller/teacher/stu"
	"Student_Mental/controller/wsService"
	"Student_Mental/docs"
	"github.com/gin-contrib/multitemplate"
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"html/template"
	"net/http"
	"path/filepath"
	"strings"
)

// @title 大学生心里健康系统
// @version 1.0
func main() {

	go wsService.Manager.Start() //websocket启动
	go TimedTasks.WriteRides()   //定时器
	r := gin.Default()
	//gin.SetMode(gin.ReleaseMode)
	//定义路由的GET方法及响应处理函数=
	//websocket
	r.GET("/ws", wsService.Handler)
	r.Static("/static", "./static")                    //加载静态资源
	r.HTMLRender = loadTemplates("./static/templates") //加载html模板
	r.Use(Middleware.Cheaklogin())                     //登入中间件
	r.Use(Middleware.Cotstime())                       //耗时统计中间件
	//渲染模板
	r.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "student_index.html", gin.H{}) }) //首页
	r.GET("/login", func(c *gin.Context) { c.HTML(http.StatusOK, "login.html", gin.H{}) })    //登入界面
	docs.SwaggerInfo.BasePath = ""

	r.GET("/404", func(c *gin.Context) {
		msg := c.Query("msg")
		c.HTML(http.StatusOK, "404.html", gin.H{
			"msg": msg,
		})
	}) //404界面处理错误
	r.GET("/public/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	r.GET("/403", func(c *gin.Context) { c.HTML(http.StatusOK, "403.html", gin.H{}) }) //403界面
	r.GET("/public/information/:status/:id", public_C.Information)                     //个人信息界面
	r.POST("/public/informationEdit/:Status/:id", public_C.InformationEdit)            //个人信息修改
	//图片上传接口
	r.POST("/public/uploadAvatar/:id", public_C.UploadAvatar)     //上传头像
	r.POST("/public/uploadCarousel/:id", public_C.UploadCarousel) //上传轮播图
	r.POST("/public/uploadMessageImg", public_C.UploadMessageImg) //上传聊天图片

	r.GET("/public/client", func(c *gin.Context) { c.HTML(http.StatusOK, "messageBox.html", gin.H{}) }) //消息框
	r.POST("/public/client/check/room", Client.GetOrCreateRoomId)                                       //检查聊天室
	r.GET("/public/client/GetMessage/:RoomId", Client.GetMessages)                                      //获取聊天记录
	r.POST("/public/client/GetMoreMessage", Client.GetMoreMessage)                                      //获取历史聊天记录
	r.GET("/public/client/GetName/:ClientId", Client.GetName)                                           //获取聊天对象名字
	r.GET("/public/getAvatar/:id", public_C.GetAvatar)                                                  //获取用户头像
	r.POST("/public/msg/getUnread", public_C.GetUnread)                                                 //获取未读消息
	r.POST("/public/msg/delUnread", public_C.DelUnread)                                                 //删除未读消息
	r.POST("/public/client/ReturnOnline", wsService.ReturnOnline)                                       //返回在线人数
	r.GET("/public/getBookingPlace/:id", public_C.GetBookingPlace)                                      //获取预约地点
	r.POST("/public/AddBookingPlace", public_C.AddBookingPlace)                                         //获取预约地点
	//api
	r.POST("/login", login.CheckUses)                         //登入
	r.GET("/exit", login.EXitLogin())                         //退出
	r.POST("/public/EditPassword/:id", public_C.EditPassword) //修改密码

	//老师路由
	teaGroup := r.Group("/teacher")
	{
		//渲染模板
		teaGroup.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "student_list.html", gin.H{}) })       //学生界面
		teaGroup.GET("/stu_add", func(c *gin.Context) { c.HTML(http.StatusOK, "student_add.html", gin.H{}) }) //添加界面

		//学生管理api
		{
			teaGroup.GET("/stu_major", teacher_stu.SelectMajor)                    //专业查询
			teaGroup.GET("/stu_class", teacher_stu.SelectClass)                    //班级查询
			teaGroup.GET("/stu_list", teacher_stu.ListData)                        //学生列表
			teaGroup.GET("/stu_list2", teacher_stu.SelectStu)                      //学生查询
			teaGroup.POST("/stu_add", teacher_stu.Add)                             //学生添加
			teaGroup.DELETE("/stu/:id", teacher_stu.Del)                           //学生删除
			teaGroup.GET("/stu/:id", teacher_stu.GetId)                            //获取一个学生
			teaGroup.PUT("/stu/:id", teacher_stu.Edit)                             //提交修改
			teaGroup.GET("/stu_test/record/:Id", teacher_stu.RecordList)           //学生考试记录列表
			teaGroup.GET("/stu_test/check/:paperId/:id", teacher_stu.CheckTheExam) //学生答题情况
		}
		//试卷api
		{
			teaGroup.GET("/Paper", teacher_que.ListPaper)
			teaGroup.GET("/Paper/:id", teacher_que.GetPaper)                                                                    //获取一张试卷
			teaGroup.GET("/Paper/add", func(c *gin.Context) { c.HTML(http.StatusOK, "questionTitleAdd.html", gin.H{}) })        //添加界面
			teaGroup.GET("/Paper/titleEdit", func(c *gin.Context) { c.HTML(http.StatusOK, "questionTitleEdit.html", gin.H{}) }) //标题编辑界面
			teaGroup.POST("/Paper/add", teacher_que.AddPaper)                                                                   // 试卷添加
			teaGroup.DELETE("/Paper/del/:id", teacher_que.DelPaper)                                                             // 试卷删除
			teaGroup.PUT("/Paper/edit", teacher_que.EditPaper)                                                                  // 试卷标题编辑
			teaGroup.GET("/Paper/edit/:id", teacher_que.EditPaper_html)                                                         //试卷编辑页面
			teaGroup.POST("/Paper/edit/:id", teacher_que.EditQusetion)                                                          //提交编辑
			teaGroup.POST("/Paper/set/:id", teacher_que.SetPaperScore)                                                          //设置分数线
			teaGroup.GET("/Paper/send/:id/:status", teacher_que.SendPaper)                                                      //发布试卷
			teaGroup.GET("/Paper/finish", teacher_que.Finish)                                                                   //完成情况
			teaGroup.GET("/Paper/finish/:id", teacher_que.FinishInfo)                                                           //完成情况详细
		}

		//轮播图设置
		{
			teaGroup.GET("/Carousel", func(c *gin.Context) { c.HTML(http.StatusOK, "carousel_list.html", gin.H{}) }) //轮播图
			teaGroup.GET("/CarouselList", setcarousel.ListData)
			teaGroup.GET("/Carousel/add", func(c *gin.Context) { c.HTML(http.StatusOK, "CarouselAdd.html", gin.H{}) }) //添加轮播图
			teaGroup.POST("/Carousel/add", setcarousel.Add)
			teaGroup.DELETE("/Carousel/del/:id", setcarousel.Del)
			teaGroup.GET("/Carousel/get/:id", setcarousel.Get)
			teaGroup.POST("/Carousel/edit/:id", setcarousel.Edit)
		}
		//聊天
		{
			teaGroup.GET("/client", tea_client.ShowClinet)                                                                 //消息列表
			teaGroup.GET("/client/msg/:toUid", func(c *gin.Context) { c.HTML(http.StatusOK, "tea_client.html", gin.H{}) }) //聊天窗口
		}
		//预约
		{
			teaGroup.GET("/Booking", func(c *gin.Context) { c.HTML(http.StatusOK, "booking.html", gin.H{}) }) //预约窗口
			teaGroup.GET("/getBooking/:id/:state", booking.GetBooking)
			teaGroup.POST("/updateBooking/:id/:state", booking.UpdateBooking)
			teaGroup.GET("/updataRedis/:sendTimestamp/:newState", booking.UpdateBookingState)
		}
		//学生分析
		{
			teaGroup.GET("/scl90", func(c *gin.Context) { c.HTML(http.StatusOK, "scl90.html", gin.H{}) }) //预约窗口
			teaGroup.GET("/getScl90", scl90.GetScl90)
			teaGroup.GET("/getScl90/:stuId", func(c *gin.Context) { c.HTML(http.StatusOK, "scl90Info.html", gin.H{}) }) //分析详情页面
			teaGroup.POST("/getScl90", scl90.GetScl90ByUserID)                                                          //获取详细信息
			teaGroup.POST("/getScl90/gptReports", scl90.GptReports)                                                     //获取详细信息
		}
	}
	//学生路由
	stuGroup := r.Group("/student")
	{
		stuGroup.GET("/", func(c *gin.Context) { c.HTML(http.StatusOK, "student_index.html", gin.H{}) })
		stuGroup.GET("/carousel", student_c.GetCarousel)                                                               //获取轮播图
		stuGroup.GET("/test", student_c.ListTest)                                                                      //在线考试模板
		stuGroup.GET("/test/:id", student_c.TakeTheExam)                                                               //进行考试,抽调试卷
		stuGroup.GET("/Paper/:id", teacher_que.GetPaper)                                                               //获取一张试卷
		stuGroup.POST("/Paper/record/:id", student_c.RecordTest)                                                       //考试记录
		stuGroup.POST("/Paper/recordScl90/:id", student_c.RecordScl90)                                                 //scl90考试记录
		stuGroup.GET("/test/record/list", student_c.RecordList)                                                        //考试记录列表
		stuGroup.GET("/test/record/check/:paperId/:id", student_c.CheckTheExam)                                        //试卷答题情况
		stuGroup.GET("/client", student_c.TeacherList)                                                                 //咨询列表
		stuGroup.GET("/client/msg/:toUid", func(c *gin.Context) { c.HTML(http.StatusOK, "stu_client.html", gin.H{}) }) //聊天窗口
		stuGroup.GET("/Booking", func(c *gin.Context) { c.HTML(http.StatusOK, "stu_booking.html", gin.H{}) })          //预约窗口
		stuGroup.GET("/getBooking/:id", student_c.GetBooking)                                                          //预约窗口
	}
	r.Run() //默认在本地8080端口启动服务

}

// 模板加载
func loadTemplates(templatesDir string) multitemplate.Renderer {
	r := multitemplate.NewRenderer()

	// 非模板嵌套
	htmls, err := filepath.Glob(templatesDir + "/htmls/*.html")
	if err != nil {
		panic(err.Error())
	}
	for _, html := range htmls {

		r.AddFromGlob(filepath.Base(html), html)
	}

	// 老师模板,老师子页面
	teacherbases, err := filepath.Glob(templatesDir + "/base/teacherbase.html")
	if err != nil {
		panic(err.Error())
	}
	teacher, err := filepath.Glob(templatesDir + "/templs/teacher/*.html")
	if err != nil {
		panic(err.Error())
	}
	// 学生模板,老师子页面
	studentbases, err := filepath.Glob(templatesDir + "/base/studentbase.html")
	if err != nil {
		panic(err.Error())
	}
	student, err := filepath.Glob(templatesDir + "/templs/student/*.html")
	if err != nil {
		panic(err.Error())
	}
	//自定义模板函数
	funcMap := template.FuncMap{
		"StringToLower": func(str string) string {
			return strings.ToLower(str)
		},
	}

	// teacherbases/和teacher/目录生成 templates map
	for _, include := range teacher {
		baseCopy := make([]string, len(teacherbases))
		copy(baseCopy, teacherbases)
		files := append(baseCopy, include)
		files = append(files, templatesDir+"/frame.html", include)
		// 加模板函数的加载方法
		r.AddFromFilesFuncs(filepath.Base(include), funcMap, files...)
		//r.AddFromFiles(filepath.Base(include), files...)
	}
	// studentbases/和student/目录生成 templates map
	for _, include := range student {
		baseCopy := make([]string, len(studentbases))
		copy(baseCopy, studentbases)
		files := append(baseCopy, include)
		files = append(files, templatesDir+"/frame.html", include)
		// 加模板函数的加载方法
		r.AddFromFilesFuncs(filepath.Base(include), funcMap, files...)
		//r.AddFromFiles(filepath.Base(include), files...)
	}
	return r
}
